

tree grammar RuleMLPresentationASTGrammar;

options 
{
   ASTLabelType = CommonTree;
   tokenVocab = RuleMLPresentationSyntax;
} 


@header
{
package org.ruleml.api.presentation_syntax_parser;

import org.ruleml.api.*;
import static java.util.Arrays.asList;
}

document [AbstractSyntax factory]
returns [AbstractSyntax.Document result] 
    : ^(DOCUMENT base[factory]? ^(PREFIXES prefix[factory]*) ^(IMPORTS importDecl[factory]*) group[factory]?)
        {
            System.out.println("Visiting document root...");
            $result = $factory.createDocument($base.result, $prefix.result, $importDecl.result, $group.result);
        }
    ;

base [AbstractSyntax factory]
returns [AbstractSyntax.Base result] 
    : ^(BASE IRI_REF)
        {
            System.out.println("Visiting document base... ["+$IRI_REF.text+"]");
            $result = $factory.createBase($IRI_REF.text);
        }
    ;

prefix [AbstractSyntax factory]
returns [AbstractSyntax.Prefix result] 
    : ^(PREFIX ID IRI_REF)
        {
            System.out.println("Visiting document prefixes... [" + $ID.text +"]");
            $result = $factory.createPrefix($factory.createName($ID.text), $IRI_REF.text);
        }
    ;



importDecl [AbstractSyntax factory]
returns [AbstractSyntax.Import result] 
    : ^(IMPORT a=IRI_REF b=IRI_REF?)
        {
            System.out.println("Visiting document imports... [" + $a.text + "]");
            $result = $factory.createImport($a.text, $factory.createProfile($a.text));
        }
    ;

group  [AbstractSyntax factory]
returns [AbstractSyntax.Group result] 
    : ^(GROUP ^(GROUP_ELEM_LIST group_element[factory]*))
        {
            System.out.println("Visiting document groups... ");
            $result = $factory.createGroup(asList(new AbstractSyntax.GroupElement[]{$group_element.result}));
        }
    ;


group_element  [AbstractSyntax factory]
returns [AbstractSyntax.GroupElement result]
    :
        rule[factory] { $result = $rule.result; }
    |
        group[factory] { $result = $group.result; }
    ;


rule  [AbstractSyntax factory]
returns [AbstractSyntax.Rule result]
    : ^(FORALL ^(VAR_LIST VAR_ID+) clause[factory])
        {
            System.out.println("Visiting rule... ");
            $result = $clause.result;
        }
    ;

clause [AbstractSyntax factory]
  returns [AbstractSyntax.Construct result]
    : 
      ^(IMPLICATION ^(AND head[factory]) ID) { $result = $head.result; }
    |
      atomic[factory] { $result = $atomic.result; }
    ;
    
head [AbstractSyntax factory]
  returns [AbstractSyntax.Construct result]
    :
      ^(EXISTS ^(VAR_LIST VAR_ID+) atomic[factory]) 
      {
        $result = $atomic.result;
      }
    | 
      atomic[factory] 
      {
        $result = $atomic.result;
      }
    ;

atomic [AbstractSyntax factory]
  returns [AbstractSyntax.Atomic result]
    :
      equal[factory] 
      {
        $result = $equal.result;
      }
      /*| subclass[factory] | atom[factory]*/ 
    ;      
    
equal [AbstractSyntax factory]
  returns [AbstractSyntax.Equal result]
    :
      ^(EQUAL ID ID) { $result = $factory.createEqual($ID.text, $ID.text); }
    ;